package cn.tedu.mall.front.service.impl;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.front.service.IFrontCategoryService;
import cn.tedu.mall.pojo.front.entity.FrontCategoryEntity;
import cn.tedu.mall.pojo.front.vo.FrontCategoryTreeVO;
import cn.tedu.mall.pojo.product.vo.CategoryStandardVO;
import cn.tedu.mall.product.service.front.IForFrontCategoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class FrontCategoryServiceImpl  implements IFrontCategoryService {

    //定义一个key的常量，用于存储分类信息
    public static final String CATEGORY_TREE_KEY="category_tree";

    //提供redis的工具类
    @Autowired
    private RedisTemplate redisTemplate;

    @DubboReference
    private IForFrontCategoryService dubboCategoryService;

    @Override
    public FrontCategoryTreeVO categoryTree() {

        FrontCategoryTreeVO frontCategoryTreeVO=null;

        //查询redis，如果redis中有数据，那么就赋值到frontCategoryTreeVO中
        //hasKey() ,用于判断redis中是否包含了指定的key
        if (redisTemplate.hasKey(CATEGORY_TREE_KEY)) {
            return frontCategoryTreeVO =
                    (FrontCategoryTreeVO) redisTemplate.boundValueOps(CATEGORY_TREE_KEY).get();
        }
        //redis种会没有分类树的信息，全查数据库
        List<CategoryStandardVO> categoryStandardVOS = dubboCategoryService.getCategoryList();
        //判断categoryStandardVOS是否为null,如果为null直接抛出异常
        if (categoryStandardVOS == null) {
            throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"分类信息为空");
        }
        //categoryStandardVOS 不为空，将分类信息的父子结构存储到map中
        HashMap<Long, List<FrontCategoryEntity>> map = new HashMap<>();
        for (CategoryStandardVO categoryStandardVO : categoryStandardVOS) {
            //categoryStandardVO 需要转换成 FrontCategoryEntity ，因为该类型中具有childrens属性
            FrontCategoryEntity frontCategoryEntity = new FrontCategoryEntity();
            BeanUtils.copyProperties(categoryStandardVO,frontCategoryEntity);
            //取出父分类的ID，作为key
            Long parentId = frontCategoryEntity.getParentId();
            //判断map中是否有该ID命名的KEY，如果有则添加到value集合中,如果没有则创建
            if (map.containsKey(parentId)){
                map.get(parentId).add(frontCategoryEntity);
            }else {
                //map中没有key
                ArrayList<FrontCategoryEntity> value = new ArrayList();
                value.add(frontCategoryEntity);
                map.put(parentId,value);
            }
        }

        //利用map中的数据构建三级分类树
        //通过顶级父类的父ID，取出一级分类信息
        List<FrontCategoryEntity> firstLevels = map.get(0L);
        if (firstLevels == null) {
            throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"当前项目中没有根分类");
        }

        //遍历firstLevels集合
        for (FrontCategoryEntity firstLevel : firstLevels) {
            //获取firstLevel的id，就表示二级分类的父ID
            Long secondLevelParentId = firstLevel.getId();
            //获取二级分类集合
            List<FrontCategoryEntity> secondLevels = map.get(secondLevelParentId);
            if (secondLevels == null) {
                log.info("当前分类缺少二级分类内容：{}",secondLevelParentId);
                continue;
            }
            //遍历二级分类集合
            for (FrontCategoryEntity secondLevel : secondLevels) {
                //获取二级分类的id，表示三级分类的父id
                Long thirdLevelParentId = secondLevel.getId();
                //获取三级集合
                List<FrontCategoryEntity> thirdLevels = map.get(thirdLevelParentId);
                if (thirdLevels==null) {
                    log.info("当前分类缺少三级分类内容：{}",thirdLevelParentId);
                    continue;
                }
                secondLevel.setChildrens(thirdLevels);
            }
            firstLevel.setChildrens(secondLevels);
        }
        frontCategoryTreeVO=new FrontCategoryTreeVO();
        frontCategoryTreeVO.setCategories(firstLevels);
        //保存到redis中
        redisTemplate.boundValueOps(CATEGORY_TREE_KEY).set(frontCategoryTreeVO,30, TimeUnit.DAYS);
        //返回结果
        return frontCategoryTreeVO;
    }
}
